package org.starapp.generator;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.starapp.plugins.freemarker.Freemarker;
import org.starapp.utils.FileUtils;
import org.starapp.utils.ListUtils;
import org.starapp.utils.StringUtils;

public class GenerateMain {

	private String tableName;
	private String className;
	private String subPackageName;
	private String suffixName;
	private String functionName;
	private Table table;

	public String getFunctionName() {
		return functionName==null?"":functionName;
	}

	public void setFunctionName(String functionName) {
		this.functionName = functionName;
	}

	public void setSuffixName(String suffixName) {
		this.suffixName = suffixName;
	}

	public void setSubPackageName(String subPackageName) {
		this.subPackageName = subPackageName;
	}

	public void setTable(Table table) {
		this.table = table;
		this.tableName = table.getTableName();
		this.className = StringUtils.convent2javaFormat(ResourceUtils.getTablePrefix(),tableName);
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String getTemplateFileName() {
		return subPackageName + ".ftl";
	}

	private String getOutputFile() {
		return ResourceUtils.getSrcOutputFolder();
	}

	private String getFolderPath() {
		return FileUtils.getProjectPath() + File.separator + getOutputFile()
				+ File.separator + subPackageName;
	}

	public String getFilePath() {
		return getFolderPath() + File.separator + className+getFunctionName()+ suffixName;
	}

	@SuppressWarnings("unchecked")
	public Map getDataMap() {
		Map data = new HashMap();
		data.put("author", ResourceUtils.getAuthor());
		data.put("package", ResourceUtils.getPackageName());
		data.put("className", table.getClassName());
		data.put("classAttrName", table.getClassAttrName());
		data.put("tableName", table.getTableName());
		data.put("subPackageName", subPackageName);
		data.put("fieldList", table.getFields());
		data.put("fkList", table.getForeignKeys());
		data.put("pkList", table.getPrimaryKeys());
		data.put("refList", table.getRefs());
		return data;
	}

	@SuppressWarnings( { "deprecation" })
	public String getTemplateFolder() {
		return java.net.URLDecoder.decode(this.getClass().getResource("/")
				.getPath())
				+ ResourceUtils.getTemplateFolder();
	}

	public Writer getOut() {
		Writer out = null;
		try {
			File file = new File(getFolderPath());
			if (!file.exists()) {
				file.mkdirs();
			}
			file = new File(getFilePath());
			if (!file.exists()) {
				file.createNewFile();
			}
			out = new OutputStreamWriter(new FileOutputStream(file));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			out = new OutputStreamWriter(System.out);
		} catch (IOException ex) {
			ex.printStackTrace();
			out = new OutputStreamWriter(System.out);
		}
		return out;
	}
	
	public static void generate(String subPackageName,String suffixName,String functionName) {
		DBConnection db = DBFactory.getDBConnection();
		// open connection;
		db.open();
		List<Table> list = db.getTableDataWithPrefix(ResourceUtils.getTablePrefix());
		if (!ListUtils.isEmpty(list)) {
			GenerateMain t = null;
			for (Table table : list) {
				if (table != null && !table.isHidden()) {
					t = new GenerateMain();
					t.setTable(table);
					t.setSubPackageName(subPackageName);
					t.setSuffixName(suffixName);
					t.setFunctionName(functionName);
					Freemarker.out(t.getTemplateFolder(), t.getDataMap(), t
							.getTemplateFileName(), t.getOut());
				}
			}
		}
		// close db
		db.close();
	}

	public static void generateEntity() {
		generate("entity", ".java", "");
	}
	public static void generateDao() {
		generate("dao", ".java", "Dao");
	}
	public static void generateService() {
		generate("service", ".java", "Service");
	}
	public static void generateRest() {
		generate("rest", ".java", "RestController");
	}

	public static void generateAction() {
		generate("action", ".java", "Controller");
	}


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		generateEntity();
	}
}
